package asia.huangxi.websocket.interceptor;

import org.springframework.http.HttpStatus;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.util.StringUtils;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpSession;
import java.util.Arrays;
import java.util.Map;
import java.util.Optional;

public class RbacHandshakeInterceptor implements HandshakeInterceptor {
    public RbacHandshakeInterceptor() {
    }

    @Override
    public boolean beforeHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception {
        System.out.println("beforeHandshake " + serverHttpRequest.getMethodValue() + "to " + serverHttpRequest.getURI() + " websocket request");
        System.out.println("serverHttpRequest.getHeaders()=" + serverHttpRequest.getHeaders());
//        boolean result = handleByCookie(serverHttpRequest);
        boolean result = handleByQueryString(serverHttpRequest);
//        boolean result = handleByHttpSession(serverHttpRequest);
        if (!result) {
            serverHttpResponse.setStatusCode(HttpStatus.FORBIDDEN);
        }
        return result;
    }

    private boolean handleByCookie(ServerHttpRequest serverHttpRequest) {
        if (serverHttpRequest instanceof ServletServerHttpRequest) {
            ServletServerHttpRequest servletServerHttpRequest = (ServletServerHttpRequest) serverHttpRequest;
            Cookie[] cookies = servletServerHttpRequest.getServletRequest().getCookies();
            Optional<Cookie> cookie = Arrays.stream(cookies).filter(c -> c.getName().equals("token")).findFirst();
            if (cookie.isPresent()) {
                String token = cookie.get().getValue();
                System.out.println("find token from cookie=" + token);
                //todo parse value
                return true;
            } else {
                System.out.println("not found token from cookie");
                return false;
            }
        }
        return false;
    }

    private boolean handleByQueryString(ServerHttpRequest serverHttpRequest) {
        if (serverHttpRequest instanceof ServletServerHttpRequest) {
            ServletServerHttpRequest servletServerHttpRequest = (ServletServerHttpRequest) serverHttpRequest;
            String token = servletServerHttpRequest.getServletRequest().getParameter("token");
            if (StringUtils.hasLength(token)) {
                System.out.println("find token from querystring=" + token);
                //todo parse value
                return true;
            } else {
                System.out.println("not found token from querystring");
                return false;
            }
        }
        return false;
    }

    private boolean handleByHttpSession(ServerHttpRequest serverHttpRequest) {
        if (serverHttpRequest instanceof ServletServerHttpRequest) {
            HttpSession httpSession = ((ServletServerHttpRequest) serverHttpRequest).getServletRequest().getSession();
            if (httpSession.getAttribute("isLogin") != null && (Boolean) (httpSession.getAttribute("isLogin"))) {
                System.out.println("check session login success");

                return true;
            } else {
                System.out.println("check session login fail");

                return false;
            }
        }
        return false;
    }

    @Override
    public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) {
        System.out.println("afterHandshake " + serverHttpRequest.getURI());
    }

}